package com.aspire.aimini.controller;

import com.aspire.aimini.service.TagService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 标签管理控制器
 *
 * @author wangguiyou
 * @date 2024-12-19
 */
@Slf4j
@RestController
@RequestMapping("/api/tags")
@RequiredArgsConstructor
@ApiTag(name = "标签管理", description = "标签相关的API接口")
public class TagController {

    private final TagService tagService;

    /**
     * 创建标签
     *
     * @param tag 标签信息
     * @return 创建的标签
     */
    @PostMapping
    @Operation(summary = "创建标签", description = "创建新的标签")
    public ResponseEntity<Tag> createTag(
            @Valid @RequestBody Tag tag,
            @Parameter(description = "用户ID") @RequestHeader("X-User-Id") Long userId) {
        log.info("创建标签: userId={}, tagName={}", userId, tag.getName());

        tag.setUserId(userId);
        Tag createdTag = tagService.createTag(tag);
        return ResponseEntity.ok(createdTag);
    }

    /**
     * 分页查询标签
     *
     * @param page      页码
     * @param size      每页大小
     * @param sort      排序字段
     * @param direction 排序方向
     * @param category  标签分类
     * @param isSystem  是否系统标签
     * @param userId    用户ID
     * @return 标签分页列表
     */
    @GetMapping
    @Operation(summary = "分页查询标签", description = "根据条件分页查询标签列表")
    public ResponseEntity<Page<Tag>> getTags(
            @Parameter(description = "页码") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") int size,
            @Parameter(description = "排序字段") @RequestParam(defaultValue = "createdAt") String sort,
            @Parameter(description = "排序方向") @RequestParam(defaultValue = "desc") String direction,
            @Parameter(description = "标签分类") @RequestParam(required = false) String category,
            @Parameter(description = "是否系统标签") @RequestParam(required = false) Boolean isSystem,
            @Parameter(description = "用户ID") @RequestHeader(value = "X-User-Id", required = false) Long userId) {

        Sort.Direction sortDirection = "asc".equalsIgnoreCase(direction) ? Sort.Direction.ASC : Sort.Direction.DESC;
        Pageable pageable = PageRequest.of(page, size, Sort.by(sortDirection, sort));

        Page<Tag> tags = tagService.getTags(pageable, category, isSystem, userId);
        return ResponseEntity.ok(tags);
    }

    /**
     * 根据ID获取标签
     *
     * @param id 标签ID
     * @return 标签信息
     */
    @GetMapping("/{id}")
    @Operation(summary = "获取标签详情", description = "根据ID获取标签详细信息")
    public ResponseEntity<Tag> getTagById(
            @Parameter(description = "标签ID") @PathVariable Long id) {
        log.info("获取标签详情: id={}", id);

        Tag tag = tagService.getTagById(id);
        return ResponseEntity.ok(tag);
    }

    /**
     * 根据名称获取标签
     *
     * @param name 标签名称
     * @return 标签信息
     */
    @GetMapping("/name/{name}")
    @Operation(summary = "根据名称获取标签", description = "根据标签名称获取标签信息")
    public ResponseEntity<Tag> getTagByName(
            @Parameter(description = "标签名称") @PathVariable String name) {
        log.info("根据名称获取标签: name={}", name);

        Tag tag = tagService.getTagByName(name);
        return ResponseEntity.ok(tag);
    }

    /**
     * 根据分类获取标签
     *
     * @param category 标签分类
     * @return 标签列表
     */
    @GetMapping("/category/{category}")
    @Operation(summary = "根据分类获取标签", description = "根据分类获取标签列表")
    public ResponseEntity<List<Tag>> getTagsByCategory(
            @Parameter(description = "标签分类") @PathVariable String category) {
        log.info("根据分类获取标签: category={}", category);

        List<Tag> tags = tagService.getTagsByCategory(category);
        return ResponseEntity.ok(tags);
    }

    /**
     * 获取热门标签
     *
     * @param limit 数量限制
     * @return 热门标签列表
     */
    @GetMapping("/popular")
    @Operation(summary = "获取热门标签", description = "获取使用次数最多的标签")
    public ResponseEntity<List<Tag>> getPopularTags(
            @Parameter(description = "数量限制") @RequestParam(defaultValue = "10") int limit) {
        log.info("获取热门标签: limit={}", limit);

        List<Tag> tags = tagService.getPopularTags(limit);
        return ResponseEntity.ok(tags);
    }

    /**
     * 获取最近使用的标签
     *
     * @param userId 用户ID
     * @param limit  数量限制
     * @return 最近使用的标签列表
     */
    @GetMapping("/recent")
    @Operation(summary = "获取最近使用的标签", description = "获取用户最近使用的标签")
    public ResponseEntity<List<Tag>> getRecentTags(
            @Parameter(description = "用户ID") @RequestHeader("X-User-Id") Long userId,
            @Parameter(description = "数量限制") @RequestParam(defaultValue = "10") int limit) {
        log.info("获取最近使用的标签: userId={}, limit={}", userId, limit);

        List<Tag> tags = tagService.getRecentTags(userId, limit);
        return ResponseEntity.ok(tags);
    }

    /**
     * 获取系统标签
     *
     * @return 系统标签列表
     */
    @GetMapping("/system")
    @Operation(summary = "获取系统标签", description = "获取所有系统预定义标签")
    public ResponseEntity<List<Tag>> getSystemTags() {
        log.info("获取系统标签");

        List<Tag> tags = tagService.getSystemTags();
        return ResponseEntity.ok(tags);
    }

    /**
     * 获取用户自定义标签
     *
     * @param userId 用户ID
     * @return 用户自定义标签列表
     */
    @GetMapping("/custom")
    @Operation(summary = "获取用户自定义标签", description = "获取用户创建的自定义标签")
    public ResponseEntity<List<Tag>> getCustomTags(
            @Parameter(description = "用户ID") @RequestHeader("X-User-Id") Long userId) {
        log.info("获取用户自定义标签: userId={}", userId);

        List<Tag> tags = tagService.getCustomTags(userId);
        return ResponseEntity.ok(tags);
    }

    /**
     * 获取未使用的标签
     *
     * @param userId 用户ID
     * @return 未使用的标签列表
     */
    @GetMapping("/unused")
    @Operation(summary = "获取未使用的标签", description = "获取用户创建但未使用的标签")
    public ResponseEntity<List<Tag>> getUnusedTags(
            @Parameter(description = "用户ID") @RequestHeader("X-User-Id") Long userId) {
        log.info("获取未使用的标签: userId={}", userId);

        List<Tag> tags = tagService.getUnusedTags(userId);
        return ResponseEntity.ok(tags);
    }

    /**
     * 更新标签
     *
     * @param id  标签ID
     * @param tag 标签信息
     * @return 更新后的标签
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新标签", description = "更新标签信息")
    public ResponseEntity<Tag> updateTag(
            @Parameter(description = "标签ID") @PathVariable Long id,
            @Valid @RequestBody Tag tag,
            @Parameter(description = "用户ID") @RequestHeader("X-User-Id") Long userId) {
        log.info("更新标签: id={}, userId={}", id, userId);

        Tag updatedTag = tagService.updateTag(id, tag);
        return ResponseEntity.ok(updatedTag);
    }

    /**
     * 删除标签
     *
     * @param id 标签ID
     * @return 删除结果
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除标签", description = "删除指定的标签")
    public ResponseEntity<Void> deleteTag(
            @Parameter(description = "标签ID") @PathVariable Long id,
            @Parameter(description = "用户ID") @RequestHeader("X-User-Id") Long userId) {
        log.info("删除标签: id={}, userId={}", id, userId);

        tagService.deleteTag(id);
        return ResponseEntity.ok().build();
    }

    /**
     * 批量删除标签
     *
     * @param ids 标签ID列表
     * @return 删除结果
     */
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除标签", description = "批量删除多个标签")
    public ResponseEntity<Void> batchDeleteTags(
            @Parameter(description = "标签ID列表") @RequestBody List<Long> ids,
            @Parameter(description = "用户ID") @RequestHeader("X-User-Id") Long userId) {
        log.info("批量删除标签: ids={}, userId={}", ids, userId);

        tagService.batchDeleteTags(ids);
        return ResponseEntity.ok().build();
    }

    /**
     * 增加标签使用次数
     *
     * @param id 标签ID
     * @return 更新后的标签
     */
    @PostMapping("/{id}/increment-usage")
    @Operation(summary = "增加标签使用次数", description = "增加标签的使用次数")
    public ResponseEntity<Tag> incrementTagUsage(
            @Parameter(description = "标签ID") @PathVariable Long id) {
        log.info("增加标签使用次数: id={}", id);

        Tag tag = tagService.incrementUsageCount(id);
        return ResponseEntity.ok(tag);
    }

    /**
     * 减少标签使用次数
     *
     * @param id 标签ID
     * @return 更新后的标签
     */
    @PostMapping("/{id}/decrement-usage")
    @Operation(summary = "减少标签使用次数", description = "减少标签的使用次数")
    public ResponseEntity<Tag> decrementTagUsage(
            @Parameter(description = "标签ID") @PathVariable Long id) {
        log.info("减少标签使用次数: id={}", id);

        Tag tag = tagService.decrementUsageCount(id);
        return ResponseEntity.ok(tag);
    }

    /**
     * 搜索标签
     *
     * @param keyword 搜索关键词
     * @param page    页码
     * @param size    每页大小
     * @return 搜索结果
     */
    @GetMapping("/search")
    @Operation(summary = "搜索标签", description = "根据关键词搜索标签")
    public ResponseEntity<Page<Tag>> searchTags(
            @Parameter(description = "搜索关键词") @RequestParam String keyword,
            @Parameter(description = "页码") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") int size) {
        log.info("搜索标签: keyword={}", keyword);

        Pageable pageable = PageRequest.of(page, size);
        Page<Tag> tags = tagService.searchTags(keyword, pageable);
        return ResponseEntity.ok(tags);
    }

    /**
     * 清理未使用的标签
     *
     * @param userId 用户ID
     * @return 清理的标签数量
     */
    @PostMapping("/cleanup-unused")
    @Operation(summary = "清理未使用的标签", description = "清理用户创建但未使用的标签")
    public ResponseEntity<Map<String, Object>> cleanupUnusedTags(
            @Parameter(description = "用户ID") @RequestHeader("X-User-Id") Long userId) {
        log.info("清理未使用的标签: userId={}", userId);

        int cleanedCount = tagService.cleanupUnusedTags(userId);

        Map<String, Object> result = Map.of(
                "cleanedCount", cleanedCount,
                "message", "清理完成");

        return ResponseEntity.ok(result);
    }

    /**
     * 获取标签分类列表
     *
     * @return 标签分类列表
     */
    @GetMapping("/categories")
    @Operation(summary = "获取标签分类列表", description = "获取所有标签分类")
    public ResponseEntity<List<String>> getTagCategories() {
        log.info("获取标签分类列表");

        List<String> categories = tagService.getTagCategories();
        return ResponseEntity.ok(categories);
    }

    /**
     * 按分类统计标签数量
     *
     * @return 分类统计结果
     */
    @GetMapping("/statistics/by-category")
    @Operation(summary = "按分类统计标签数量", description = "统计每个分类下的标签数量")
    public ResponseEntity<Map<String, Long>> getTagCountByCategory() {
        log.info("按分类统计标签数量");

        Map<String, Long> statistics = tagService.getTagCountByCategory();
        return ResponseEntity.ok(statistics);
    }

    /**
     * 获取标签使用统计
     *
     * @param id 标签ID
     * @return 使用统计信息
     */
    @GetMapping("/{id}/usage-statistics")
    @Operation(summary = "获取标签使用统计", description = "获取标签的详细使用统计信息")
    public ResponseEntity<Map<String, Object>> getTagUsageStatistics(
            @Parameter(description = "标签ID") @PathVariable Long id) {
        log.info("获取标签使用统计: id={}", id);

        Map<String, Object> statistics = tagService.getTagUsageStatistics(id);
        return ResponseEntity.ok(statistics);
    }

    /**
     * 批量创建标签
     *
     * @param tags   标签列表
     * @param userId 用户ID
     * @return 创建的标签列表
     */
    @PostMapping("/batch")
    @Operation(summary = "批量创建标签", description = "批量创建多个标签")
    public ResponseEntity<List<Tag>> batchCreateTags(
            @Valid @RequestBody List<Tag> tags,
            @Parameter(description = "用户ID") @RequestHeader("X-User-Id") Long userId) {
        log.info("批量创建标签: count={}, userId={}", tags.size(), userId);

        // 设置用户ID
        tags.forEach(tag -> tag.setUserId(userId));

        List<Tag> createdTags = tagService.batchCreateTags(tags);
        return ResponseEntity.ok(createdTags);
    }

    /**
     * 合并标签
     *
     * @param sourceId 源标签ID
     * @param targetId 目标标签ID
     * @return 合并结果
     */
    @PostMapping("/{sourceId}/merge/{targetId}")
    @Operation(summary = "合并标签", description = "将源标签合并到目标标签")
    public ResponseEntity<Map<String, Object>> mergeTags(
            @Parameter(description = "源标签ID") @PathVariable Long sourceId,
            @Parameter(description = "目标标签ID") @PathVariable Long targetId,
            @Parameter(description = "用户ID") @RequestHeader("X-User-Id") Long userId) {
        log.info("合并标签: sourceId={}, targetId={}, userId={}", sourceId, targetId, userId);

        tagService.mergeTags(sourceId, targetId);

        Map<String, Object> result = Map.of(
                "message", "标签合并成功",
                "sourceId", sourceId,
                "targetId", targetId);

        return ResponseEntity.ok(result);
    }

    /**
     * 检查标签名称是否存在
     *
     * @param name 标签名称
     * @return 检查结果
     */
    @GetMapping("/check-name")
    @Operation(summary = "检查标签名称是否存在", description = "检查指定的标签名称是否已存在")
    public ResponseEntity<Map<String, Object>> checkTagNameExists(
            @Parameter(description = "标签名称") @RequestParam String name) {
        log.info("检查标签名称是否存在: name={}", name);

        boolean exists = tagService.isTagNameExists(name);

        Map<String, Object> result = Map.of(
                "name", name,
                "exists", exists);

        return ResponseEntity.ok(result);
    }
}